import random
from database.park_location_record_table import ParkLocationRecordTable
from manager.lock_manager import LockManager
from model.park_spider import ParkSpider
from model.park_platform import ParkPlatform
from model.car_number import CarNumber
from model.result import Result
from concurrent.futures import ThreadPoolExecutor

import requests
import dateutil.parser as dateutil
from urllib import parse
import common.http as http
import spider_config
from common.logger import logger

park_ids = [395,453,404,401,562,288,434,340,337,333,298,176,166,142,569,373,191,377,573,572,566,500,495,491,471,353,213,552,240,571,428,553,265,163,550,356,540,396,156,357,393,287,152,363,286,202,510,321,204,419,443,508,435,219,210,190,178,387,360,359,313,195,432,215,374,291,158,249,171,388,221,153,247,339,320,197,165,344,198,416,462,217,583,281,220,184,268,378,283,236,278,397,507,502,466,456,438,405,137,135,128,127,123,113,112,538,440,349,469,136,133,132,131,319,290,116,115,114,444,431,367,134,130,129,124,478,408,126,125,250,417,200,348,322,222,522,468,209,485,380,498,394,118,459,334,304,173,139,122,335,177,586,138,120,117,530,235,214,296,276,515,399,355,293,164,183,439,223,365,242,352,175,382,398,336,427,407,253,484,264,541,509,426,211,460,409,351,111,513,505,442,206,189,159,332,549,521,329,182,551,192,167,577,487,481,187,584,254,237,424,523,324,570,455,381,345,311,579,148,547,512,548,246,147,259,272,170,392,384,203,193,446,169,415,300,216,483,261,168,580,368,228,482,232,230,449,567,554,473,457,390,514,266,425,140,350,437,273,243,186,546,545,284,180,188,309,144,150,418,354,239,429,310,568,447,519,474,458,285,277,199,518,174,196,461,282,233,477,274,414,292,423,308,452,410,520,526,323,270,492,160,561,558,227,143,497,544,450,479,383,260,226,224,201,179,490,420,375,585,331,257,149,476,475,406,154,269,422,504,294,234,499,252,342,256,255,212,489,338,205,162,145,258,141,517,346,185,543,537,146,400,557,379,343,494,480,436,385,364,361,280,241,225,218,161,576,445,317,307,271,267,262,157,155,451,386,347,229,372,251,314,529,172,231,464,306,369,151,527,525,194,433,486,467,454,305,297,578,588,465,244,318,559,501,496,539,341,330,279,275,556,208,358,302,430,391,581,248,463,370,555,488,528,493,207,238,303,362,564,448,371,295,575,516,511,326,119,121,289,325,315,506,524,421,402,316,312,328]

class EtcpParkSpider(ParkSpider):
    def platform(self) -> ParkPlatform:
        return ParkPlatform(spider_config.etcp_park_id)

    def in_wanda_parking(self, carNumber: CarNumber) -> Result:
        
        merberid = random.randint(1, 99999999999)
        
        url = 'https://api.wandacm.com.cn/client/v2/order/calculate'
        
        headers = {
            "memberId" : str(merberid),
            "Content-Type": "application/json",
            "Host": "api.wandacm.com.cn",
        }
        
        data = {
            "discountType":"none",
            "memberId":str(merberid),
            "parkingId": str(395),
            "plateNumber":str(carNumber)
        }
        
        retry = 0
        while True:
            try:
                rsp = http.post(url, headers=headers, json=data)
                rspJson = rsp.json()
                logger.debug(rspJson)
                if rspJson["status"] == 12022 or rspJson["status"] == 200:
                    return True
                break
            except Exception as e:
                retry += 1
                if retry > 3:
                    logger.error(f"etcp error: {repr(e)}")
                    break
        
        return False
        
    def query_wanda_parking(self, carNumber: CarNumber, park_id) -> Result:
        
        merberid = random.randint(1, 99999999999)
        
        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber
        
        url = 'https://api.wandacm.com.cn/client/v2/order/calculate'
        
        headers = {
            "memberId" : str(merberid),
            "Content-Type": "application/json",
            "Host": "api.wandacm.com.cn",
        }
        
        data = {
            "discountType":"none",
            "memberId":str(merberid),
            "parkingId": str(park_id),
            "plateNumber":str(carNumber)
        }
        retry = 0
        
        while True:
            try:
                rsp = http.post(url, headers=headers, json=data)
                rspJson = rsp.json()
                logger.debug(f"{park_id} : {rspJson}")
                if rspJson["status"] != 12022:
                    logger.warning(f"万达车场异常 {carNumber} {park_id} : {rspJson}")
                if rspJson["status"] == 200:
                    result.success = True
                    result.enter_time = dateutil.parse(rspJson["data"]["entryTime"])
                    result.price = rspJson["data"]["totalAmount"] / 100
                    with ParkLocationRecordTable(spider_config.etcp_park_id) as db:
                        record = db.query(park_id)
                        if record:
                            result.park_name = record
                break
            except Exception as e:
                retry += 1
                if retry > 3:
                    logger.error(f"etcp error: {repr(e)}")
                    break
        return result
        
    def query_wanda(self, carNumber: CarNumber) -> Result:
        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber
        
        if not self.in_wanda_parking(carNumber):
            return result
        
        thread_pool = ThreadPoolExecutor(max_workers=100)
        futures = []
        for park_id in park_ids:
            futures.append(thread_pool.submit(self.query_wanda_parking, carNumber, park_id))
        
        for future in futures:
            r : Result = future.result()
            if r.success:
                result = r
                break
        
        thread_pool.shutdown(wait=False)
        
        if not result.success:
            logger.error(f"etcp query {carNumber} failed")
            
        return result

    def query(self, carNumber: CarNumber) -> Result:
        return self.query_wanda(carNumber)
    
        openid = "orbwc0UIrhCWGyFeYRniucjEUb8k"

        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber

        params = {"plateNumber": str(carNumber), "openId": openid}

        url = "https://api-c-prod.etcp.cn/parking-core/parking/v1/record"

        headers = {"openId": openid}

        with LockManager.instance().get(self.platform().id, openid):
            rsp = http.get(
                url,
                headers=headers,
                params=params,
                proxies=self.getProxy(),
                timeout=self.getTimeout(),
            )

            if rsp.status_code != 200:
                result.error_code = rsp.status_code
                result.message = rsp.text
                return result

            rspJson = rsp.json()

            logger.debug(f"etcp park query {carNumber}: {rspJson}")

            if rspJson["code"] != 0:
                result.error_code = rspJson["code"]
                result.message = rspJson["message"] if "message" in rspJson else ""
                return result

            recordSynId = rspJson["data"]["recordSynId"]

            params = {
                "paySource": 34,
                "openId": openid,
                "recordSynId": recordSynId,
            }

            url = "https://api-c-prod.etcp.cn/parking-core/fee/v1/parking/online"

            rsp = http.get(
                url,
                headers=headers,
                proxies=self.getProxy(),
                params=params,
                timeout=self.getTimeout(),
            )

        if rsp.status_code != 200:
            result.error_code = rsp.status_code
            result.message = rsp.text
            return result

        rspJson = rsp.json()

        result.error_code = rspJson["code"]
        result.success = rspJson["code"] == 0
        result.message = rspJson["message"] if "message" in rspJson else ""

        if not result.success:
            return result

        result.enter_time = dateutil.parse(rspJson["data"]["entranceTime"])

        if rspJson["data"]["recordBusinessType"] != "TEMP_PARKING":
            result.remark = "非临时车"
            return result

        result.park_name = rspJson["data"]["parkingName"]
        result.price = rspJson["data"]["needPayFee"]

        logger.debug(f"{result}")

        return result
